﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using WiimoteLib;
using InTheHand.Net;
using InTheHand.Net.Bluetooth;
using InTheHand.Net.Sockets;
using System.Threading;
using Microsoft.Win32;
using System.Drawing.Imaging;

namespace WiiConnects {
    public partial class frmWiiConnect : Form {

        
        public int IRwidth = 1023;
        public int IRheight = 767;
        Wiimote wm;
        BluetoothClient bc;
        IRSensor sensore_dx, sensore_sx;
        String batteria;
        private Bitmap b;
        Graphics g;
        public frmWiiConnect() {
            
            InitializeComponent();
            txtWiimoteID.Text = WiiConnects.Properties.Settings.Default.WiiMoteAddress;
        }

        private void Form1_Load(object sender, EventArgs e) {
            b = new Bitmap(pbWii.Width, pbWii.Height, PixelFormat.Format24bppRgb);
            g = Graphics.FromImage(b);
        }

        private void bntConnect_Click(object sender, EventArgs e) {
            if (wm == null) {

                ConnettiBluetooth();
                ConnettiWiimote(sender, e);
                if (wm != null) btnConnect.Text = "Disconnect";
            } else {
                btnConnect.Text = "Connect";
                wm.WiimoteChanged -= wm_WiimoteChanged;
               
                wm.Disconnect();
                wm.Dispose();
                wm = null;
                
                BluetoothAddress addr = BluetoothAddress.Parse(txtWiimoteID.Text);


                BluetoothSecurity.RemoveDevice(addr);

                BluetoothDeviceInfo device = new BluetoothDeviceInfo(addr);
                Guid svcClass = BluetoothService.HumanInterfaceDevice;
                device.SetServiceState(svcClass, false);
                device.Refresh();
                BluetoothSecurity.RevokePin(addr);
                


                bc.Client.Dispose();
                bc.Close();
                
                bc.Dispose();
                
                bc = null;
            }
        }
 #region Wiimote
        private delegate void UpdateWiimoteStateDelegate(WiimoteChangedEventArgs args);

        void ConnettiWiimote(object sender, EventArgs e)
        {
            commentDebug("Connetti Wiimote chiamato");
            try
            {
                wm = new Wiimote();
                
                wm.Connect();
                wm.SetReportType(InputReport.IRAccel, true);
                wm.SetLEDs(false, true, true, false);
                wm.WiimoteChanged += wm_WiimoteChanged;
                
                //return 
                //true;
            }
            catch (WiimoteLib.WiimoteNotFoundException exc)
            {
               
                commentDebug("ERRORE: " + exc.Message);
                wm.Disconnect();
                wm.Dispose();
                wm = null;
                //return false;
            }

        }


       
        
       

       
        private void wm_WiimoteChanged(object sender, WiimoteChangedEventArgs args)
        {

            UpdateState(args);
        }

        //private delegate void UpdateExtensionChangedDelegate(WiimoteExtensionChangedEventArgs args);
       
        private void UpdateState(WiimoteChangedEventArgs args)
        {
            BeginInvoke(new UpdateWiimoteStateDelegate(UpdateWiimoteChanged), args);
           

        }
        public void UpdateWiimoteChanged(WiimoteChangedEventArgs args)
        {
            
            commentDebug("Wiimote Changed:");
            WiimoteState ws = args.WiimoteState;
            for (int i = 0; i < 4; i++)
            {
                if (ws.IRState.IRSensors[i].Found)
                {
                    //Console.WriteLine("Sensori:" + ws.IRState.IRSensors[i].Position.X + " > " + IRwidth / 2);
                    if (ws.IRState.IRSensors[i].RawPosition.X > IRwidth / 2)
                    {
                        //cornice destra
                        sensore_dx = ws.IRState.IRSensors[i];
                    }
                    else
                    {
                        //cornice sinistra
                        sensore_sx = ws.IRState.IRSensors[i];
                    }
                }
            }
            
            g.Clear(Color.Black);
            g.DrawEllipse(new Pen(Color.OrangeRed), sensore_sx.Position.X * pbWii.Width, sensore_sx.Position.Y * pbWii.Height, 5, 5);
            g.DrawEllipse(new Pen(Color.YellowGreen), sensore_dx.Position.X * pbWii.Width, sensore_dx.Position.Y * pbWii.Height, 5, 5);
            pbWii.Image = b;
            if(batteria != null) batteria = (ws.Battery > 0xc8 ? 0xc8 : (int)ws.Battery).ToString();
        

        }
        #endregion
        public void ConnettiBluetooth() {

            try {
                BluetoothRadio.PrimaryRadio.Mode = RadioMode.Connectable;
                bc = new BluetoothClient();
            } catch (Exception btREx) {
                //appLog.WriteEntry("Bluetooth error:" + btREx.Message, System.Diagnostics.EventLogEntryType.Error);
                commentDebug("Bluetooth error:" + btREx.Message);
            }
            try {
                
                commentDebug("Cerco dispositivi Bluetooth. Attendere.");
                BluetoothDeviceInfo[] bdi = bc.DiscoverDevices(10);
                
                commentDebug("Trovati " + bdi.Length + " dispositivi.");
                for (int btCount = 0; btCount < bdi.Length; btCount++) {
                    //commentDebug("- Trovato dispositivo " + bdi[btCount].DeviceName + " con indirizzo: "+ bdi[btCount].DeviceAddress.ToString() + ".");
                    commentDebug(bdi[btCount].DeviceAddress.ToString() + "..." + bdi[btCount].DeviceAddress.ToInt64() + " == " + Convert.ToInt64(Properties.Settings.Default.WiiMoteAddress, 16) );
                    if (bdi[btCount].DeviceName == "Nintendo RVL-CNT-01" && bdi[btCount].DeviceAddress.ToInt64() == Convert.ToInt64(Properties.Settings.Default.WiiMoteAddress,16)) {

                        commentDebug("- Wiimote già connesso? " + bdi[btCount].Connected);

                        if (bdi[btCount].Connected) {
                            /*
                                bdi[btCount].SetServiceState(BluetoothService.HumanInterfaceDevice, false);
                             BluetoothSecurity.RemoveDevice(bdi[btCount].DeviceAddress);
                             Console.WriteLine("- - Era connesso, rimuovo...");
                             Thread.Sleep(15000);
                             bdi[btCount].SetServiceState(BluetoothService.HumanInterfaceDevice, false);
                             bdi[btCount].ShowDialog();
                             bc.Client.Disconnect(false) ;
                             bc.Dispose();
                             bc = null;
                             if (wm != null) {
                                 wm.Disconnect();
                                 wm.Dispose();
                                 wm = null;
                             }
                             ConnettiBluetooth();
                             * */
                        }
                        else {
                            commentDebug("- - Non è connesso. " + bdi[btCount].DeviceAddress + " + " + bdi[btCount].GetHashCode() + " - ");

                            BluetoothEndPoint ep = new BluetoothEndPoint(bdi[btCount].DeviceAddress, BluetoothService.HumanInterfaceDevice);
                            
                            /*
                            Try
                            If (mote.InstalledServices.Length = 0) Then
                            mote.SetServiceState(InTheHand.Net.Bluetooth.BluetoothService.HumanInterfaceDevice, True) 
                            Else
                            InTheHand.Net.Bluetooth.BluetoothSecurity.RemoveDevice(mote.DeviceAddress)
                            mote.SetServiceState(InTheHand.Net.Bluetooth.BluetoothService.HumanInterfaceDevice, True)
                            End If
                            Catch ex As Exception
                            MsgBox(ex.Message, MsgBoxStyle.Exclamation)
                            End Try
                             */

                            if (bdi[btCount].InstalledServices.Length > 0) {
                                commentDebug("- - Ci sono " + bdi[btCount].InstalledServices.Length + " servizi installati");
                                BluetoothSecurity.RemoveDevice(bdi[btCount].DeviceAddress);
                                Thread.Sleep(2000);


                            } else {
                                commentDebug("- - Nessun servizio installato");

                            }
                            commentDebug("- - Lo stato attivo di HumanInterfaceDevice è " + bdi[btCount].GetServiceRecords(BluetoothService.HumanInterfaceDevice));

                            bdi[btCount].SetServiceState(BluetoothService.HumanInterfaceDevice, false);
                            commentDebug("- - Temporaneamente HumanInterfaceDevice è " + bdi[btCount].GetServiceRecords(BluetoothService.HumanInterfaceDevice));
                            bdi[btCount].SetServiceState(BluetoothService.HumanInterfaceDevice, true);
                            commentDebug("- - Adesso lo stato attivo di HumanInterfaceDevice è " + bdi[btCount].GetServiceRecords(BluetoothService.HumanInterfaceDevice));

                         

                        }
                        commentDebug("Connected to Bluetooth device");
#if DEBUG
      
#endif
                    }
                }
            } catch (Exception bdiEx) {
                //appLog.WriteEntry("Bluetooth error:" + bdiEx.Message, System.Diagnostics.EventLogEntryType.Error);
                MessageBox.Show("Errore: " + bdiEx.Message);
            }
        }

        private void commentDebug(string p) {
            Console.WriteLine(p);
            statusLabel.Text = p;
            
        }

        private void btnSalva_Click(object sender, EventArgs e) {
            Properties.Settings.Default.WiiMoteAddress = txtWiimoteID.Text;
            Properties.Settings.Default.Save();
        }
    }
}
